using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.Practices.ServiceLocation;

namespace Beaker.Injection.Desktop
{
	internal sealed class QueryContainerServiceLocatorAdapter
		: IServiceLocator
	{
		private readonly IQueryContainer _queryContainer ;

		public QueryContainerServiceLocatorAdapter(IQueryContainer queryContainer)
		{
			Contract.Requires<ArgumentNullException>(queryContainer != null, "queryContainer");
			_queryContainer = queryContainer;
		}

		public object GetService(Type serviceType)
		{
			if (serviceType == null)
				throw new ArgumentNullException("serviceType");

			return _queryContainer.GetInstance(serviceType);
		}

		public object GetInstance(Type serviceType)
		{
			if (serviceType == null)
				throw new ArgumentNullException("serviceType");

			return _queryContainer.GetInstance(serviceType);
		}

		public object GetInstance(Type serviceType, string key)
		{
			if (serviceType == null)
				throw new ArgumentNullException("serviceType");

			if (string.IsNullOrEmpty( key ))
				return GetInstance(serviceType);

			throw new NotSupportedException("Keyed registration is not supported by Simple Injector.");
		}

		public IEnumerable<object> GetAllInstances(Type serviceType)
		{
			return _queryContainer.GetAllInstances(serviceType);
		}

		public TService GetInstance<TService>()
		{
			return (TService)_queryContainer.GetInstance(typeof(TService));
		}

		public TService GetInstance<TService>(string key)
		{
			if (string.IsNullOrEmpty(key))
				return (TService)_queryContainer.GetInstance(typeof(TService));

			throw new NotSupportedException("Keyed registration is not supported by Simple Injector.");
		}

		public IEnumerable<TService> GetAllInstances<TService>()
		{
			return _queryContainer.GetAllInstances(typeof(TService)).Cast<TService>();
		}
	}
}